#include "state_tutorial.h"

namespace tutorial
{
    bn::string_view text[] =
    {
        "Welcome to notenogram's tutorial mode! Press A to go forward, START to quit anytime.",
        "Chances are this is the first time you've ever gave a picross/nonogram game a go, and if so, this tutorial on Picross 101 is here to help!",
        //2 - basic rules
        "The objective of solving a picross puzzle is filling squares/cells in a finite rectangular grid according to numeric hints on the left and the top.",
        //3
        "Kinda like regular crossword, except you get a pixel picture as a result of completion (also \"picross\" = \"picture crossword\", so there you have it).",
        "Each numeric row on the left or column on top represents the number of colored squares in the grid's respective row or column.",
        "So if second row from the top says '5', it means second row from the top of the grid should have five colored squares.",
        "You can color a square by moving the pen cursor to it using the D-pad and pressing A button.",
        //7 - separated
        "If there's more than one number of colored squares hinted at, it means that these groups of squares are separated by at least one empty square.",
        //8
        "After all, if you color the squares without separating them, these groups will mash into one and won't exist separately anymore.",
        "This can be clearly observed when coloring squares in create mode, so feel free to play around with it as well!",
        "Also worth mentioning is that these groups should be placed from left to right row-wise and from top to bottom column-wise.",
        //11 - separated order
        "Example: a column/row of four cells is marked with '1' and '2' number hints.",
        //12
        "For column you need to color the topmost square first, then skip the next cell below, then color the remaining two cells below.",
        //13
        "Same with the row of cells - start with one colored square from the left, then skip the next one to the right, then color the rest.",
        //14
        "These empty squares can be crossed out (using B button) to easily keep track of them.",
        "That's all there is to the basic rules. Now, let's smoothly transition to our first Picross Strategy Tip!",
        "Picross Strategy Tip #1: always color squares that you know should be colored, and always cross out empty squares you know should be empty.",
        //17 tip 1 full
        "If you're solving a 5x5 puzzle and there's a row or a column marked with number '5', it means the entire row or column should be colored.",
        //18 empty
        "Likewise if a row or column has no number hints, this means there are no colored squares and you can cross them out entirely!",
        "This also can be used for the groups of different amounts of squares - ",
        "if they span the entire row or column and can be separated by no more than one empty square inbetween, they can be safely marked accordingly.",
        //21 group
        "Example - a group of '1', '2' and '3' colored square hints next to a row of 8 cells:",
        "first cell from the left colored, next crossed, next two colored, then next one crossed, then the remaining three colored.",
        "That's 6 colored squares + 2 empty = 8 squares in total in this row. A perfect fit!",
        "Here's another, more advanced way in how this tip can be used:",
        //25 advanced
        "if you have some squares from a group already colored and you know that there should be no more groups of colored squares before or after this one,",
        "count the remaining squares that could make up the full group from both sides and cross out the remaining ones.",
        "This is how you can try to guess where to color four squares on an 8-square row if you already have two colored in the middle.",
        "This brings us to Picross Strategy Tip #2: use cell counting for \"predicting\" colored cell placements!",
        //29 tip 2 single 0
        "Often you may not know where exactly to color squares in a certain row or column, in which case deduction might come in handy.",
        "Try and imagine fitting the colored squares on the row/column starting from the left/top, then try fitting them starting from the right/bottom.",
        "Then notice which squares overlap - these are the squares that should be colored!",
        "Cross markings can help you with imaginary placements, just be sure to erase them afterwards.",
        "Example: if you have a row of 10 squares and you need to fit '6' colored squares onto it, here's what you would do:",
        //34 1
        "1. Imagine coloring (but don't color yet) six squares starting from the leftmost one and cross out (for real) the remaining four.",
        "2. Then imagine coloring six squares from the rightmost one and cross out the remaining four closer to the left.",
        "3. The remaining empty squares can now be safely colored and the cross marks removed afterwards.",
        "While this tip can work for several square groups, too, it usually depends on the numbers you're working with.",
        //38 tip 2 multiple 0
        "A working example - predicting the placement of '5' and '3' colored squares on a row of 10 -",
        "first imagine coloring from the left with one square gap between,",
        "then imagine coloring from the right (but starting with group of three), again with one square inbetween.",
        "Here, the remaining squares should be colored 100%, but that may not work for other numbers.",
        "For example, this won't work with single colored square groups or for less than half of the row or column of colored squares.",
        "Last Picross Strategy Tip for now, and it's the only tip that can be applied for video games.",
        "Picross Strategy Tip #3: take risks!",
        "If you're not sure what to do and making a mistake isn't critical, take a guess and color the square you think should be colored!",
        "Whether you're right or not, you'll still gain some valuable information that will help you out in solving the puzzle.",
        "Truth be told, not every picross puzzle pattern is designed to be logically solveable 100% (and this game is no exception).",
        "As long as you expect minimal losses from it, some guesswork can definitely be of use.",
        "...Aaaaand that's it for now! Hope this was easy enough to understand for getting started with notenogram's 12x12 puzzles.",
        "With the basics now in your grasp, try solving puzzle #1 in the Things category, as it should be the easiest one of them!",
        "Let me know if there is anything I should clarify or add to this tutorial via game's itch.io page's comment section.",
        "I myself am still not very well-versed in picross, so in case I made a mistake or something be sure to notify me!",
        "Have fun д"
    };
}

TutorialMode::TutorialMode() : GameState(),
    bg_pattern(buildBG()), map(bg_pattern.map()),
    script_ptr(0),symbol_ptr(0),line_ptr(0),
    bg_redrawn(false), sprites_redrawn(false)
{
    initScreen();
}

TutorialMode::TutorialMode(bn::sprite_text_generator* stg) :
    GameState(), bg_pattern(buildBG()), map(bg_pattern.map()),
    _text(new text(stg)), script_ptr(0),symbol_ptr(0),line_ptr(0),
    bg_redrawn(false), sprites_redrawn(false)
{
    initScreen();
}

TutorialMode::TutorialMode(text* stg) :
    GameState(), bg_pattern(buildBG()), map(bg_pattern.map()),
    _text(new text(stg)), script_ptr(0),symbol_ptr(0),line_ptr(0),
    bg_redrawn(false), sprites_redrawn(false)
{
    initScreen();
}

void TutorialMode::initScreen()
{
    PaperSheetPattern_Holed();
    refreshScreen(map);
    _text->redraw(tutorial::text[0]);
    //sprite.valid(true);
    //sprite->set_visible(false);
}

int TutorialMode::drawText()
{
    _text->output_Typewriter(tutorial::text[script_ptr], symbol_ptr, line_ptr, 0, text_redraw_start_y);
    if (bn::keypad::a_pressed())
    {
        line_ptr = symbol_ptr = 0;
        if (++script_ptr >= 54)
        {
            script_ptr = 0;
            return 0;
        }
        else
        {
            switch (script_ptr)
            {
            case 2:
                BasicRulesExample(false,false);
                break;
            case 3:
                BasicRulesExample(true,false);
                break;
            case 5:
                BasicRulesExample(true,true);
                break;
            case 7:
                clearBG();
                SeparatedSquaresExample(true);
                break;
            case 8:
                SeparatedSquaresExample(false);
                break;
            case 11:
            case 15:
            case 20:
            case 24:
            case 28:
            case 37:
            case 42:
                clearBG();
                break;
            case 12:
                SeparatedSquaresOrderExample(false, false);
                break;
            case 13:
                SeparatedSquaresOrderExample(true, false);
                break;
            case 14:
                SeparatedSquaresOrderExample(false, true);
                break;
            case 17:
                clearBG();
                StrategyTipOne_Full();
                break;
            case 18:
                clearBG();
                StrategyTipOne_Empty();
                break;
            case 21:
                StrategyTipOne_Group();
                break;
            case 25:
                StrategyTipOne_Advanced();
                break;
            case 29:
                StrategyTipTwo_Single(0);
                break;
            case 34:
                StrategyTipTwo_Single(1);
                break;
            case 35:
                StrategyTipTwo_Single(2);
                break;
            case 36:
                StrategyTipTwo_Single(3);
                break;
            case 38:
                StrategyTipTwo_Multiple(0);
                break;
            case 39:
                StrategyTipTwo_Multiple(1);
                break;
            case 40:
                StrategyTipTwo_Multiple(2);
                break;
            case 41:
                StrategyTipTwo_Multiple(3);
                break;
            default:
                break;
            }
            refreshScreen(map);
            _text->redraw(tutorial::text[script_ptr]);
        }
    }
    if (bn::keypad::start_held())
        return 0;
    return -1;
}

//clearing the screen's area for puzzle examples
void TutorialMode::clearBG()
{
    sprite->set_visible(false);
    for (int i = map_redraw_start_x; i < map_redraw_width; ++i)
    {
        for (int j = map_redraw_start_y; j < map_redraw_height; ++j)
        {
            setCellTile(i, j, 1);
        }
    }
}

//heart picross puzzle
//parameter - checks whether to color in the solution
void TutorialMode::BasicRulesExample(bool squares_colored, bool highlight)
{
    //row hints
    setCellTile(12, 10, 4);
    setCellTile(13, 10, 6);
    setCellTile(14, 10, 6);
    setCellTile(15, 10, 6);
    setCellTile(16, 10, 4);
    //column hints
    setCellTile(10, 11, 4);
    setCellTile(11, 11, 4);
    setCellTile(11, 12, 8);
    setCellTile(11, 13, 6);
    setCellTile(11, 14, 4);
    //puzzle solution
    if (squares_colored)
    {
        setCellTile(12, 12, 3);
        setCellTile(13, 11, 3);
        setCellTile(13, 12, 3);
        setCellTile(13, 13, 3);
        setCellTile(14, 12, 3);
        setCellTile(14, 13, 3);
        setCellTile(14, 14, 3);
        setCellTile(15, 11, 3);
        setCellTile(15, 12, 3);
        setCellTile(15, 13, 3);
        setCellTile(16, 12, 3);
    }

    if (highlight)
    {
        sprite = buildSprite(bn::sprite_items::bar_horz, -9, -8);
        sprite->set_visible(true);
    }
}
//single-row example of separated square groups
//parameter - flag that decides which example to draw (upper is correct, lower is not)
void TutorialMode::SeparatedSquaresExample(bool upper_row)
{
    int row_index = upper_row ? 10 : 14;
    //row hints
    setCellTile(12, row_index, 4);
    setCellTile(13, row_index, 4);
    setCellTile(15, row_index, 4);
    setCellTile(16, row_index, 4);
    //column hints
    setCellTile(10, row_index+1, 5);
    setCellTile(11, row_index+1, 5);
    //colored cells
    setCellTile(12, row_index+1, 3);
    setCellTile(13, row_index+1, 3);
    setCellTile(15, row_index+1, 3);
    setCellTile((upper_row ? 16 : 14), row_index+1, 3);

    if (!upper_row)
    {
        sprite = buildSprite(bn::sprite_items::good, 40, -22);
        sprite->set_visible(true);
    }
}
//single-row/column example of ordering separated square groups
//parameter - flags that decide which example to draw (row or column or crossed squares)
void TutorialMode::SeparatedSquaresOrderExample(bool row, bool cross)
{
    if (row)
    {
        setCellTile(13, 10, 4);
        setCellTile(14, 10, 5);
        setCellTile(15, 10, 3);
        setCellTile(17, 10, 3);
        setCellTile(18, 10, 3);
        sprite = buildSprite(bn::sprite_items::arrow_row, -9, -8);
        sprite->set_visible(true);
    }
    else if (cross)
    {
        setCellTile(16, 10, 2);
        setCellTile(10, 13, 2);
    }
    else
    {

        setCellTile(10, 10, 4);
        setCellTile(10, 11, 5);
        setCellTile(10, 12, 3);
        setCellTile(10, 14, 3);
        setCellTile(10, 15, 3);
        sprite = buildSprite(bn::sprite_items::arrow_col, -9, -8);
        sprite->set_visible(true);
    }


}
//plus sign picture puzzle
void TutorialMode::StrategyTipOne_Full()
{
    //numeric hints
    setCellTile(12, 10, 4);
    setCellTile(13, 10, 4);
    setCellTile(15, 10, 4);
    setCellTile(16, 10, 4);
    setCellTile(14, 10, 8);

    setCellTile(11, 11, 4);
    setCellTile(11, 12, 4);
    setCellTile(11, 13, 8);
    setCellTile(11, 14, 4);
    setCellTile(11, 15, 4);

    //colored square column
    setCellTile(14, 11, 3);
    setCellTile(14, 12, 3);
    setCellTile(14, 13, 3);
    setCellTile(14, 14, 3);
    setCellTile(14, 15, 3);

    //colored square row
    setCellTile(12, 13, 3);
    setCellTile(13, 13, 3);
    setCellTile(14, 13, 3);
    setCellTile(15, 13, 3);
    setCellTile(16, 13, 3);
}

//inverted plus sign picture puzzle
void TutorialMode::StrategyTipOne_Empty()
{
    //numeric hints
    setCellTile(12, 10, 5);
    setCellTile(13, 10, 5);
    setCellTile(15, 10, 5);
    setCellTile(16, 10, 5);

    setCellTile(11, 11, 5);
    setCellTile(11, 12, 5);
    setCellTile(11, 14, 5);
    setCellTile(11, 15, 5);

    //empty column
    setCellTile(14, 11, 2);
    setCellTile(14, 12, 2);
    setCellTile(14, 13, 2);
    setCellTile(14, 14, 2);
    setCellTile(14, 15, 2);

    //empty row
    setCellTile(12, 13, 2);
    setCellTile(13, 13, 2);
    setCellTile(14, 13, 2);
    setCellTile(15, 13, 2);
    setCellTile(16, 13, 2);
}
//one+two+three squares on 8 square row
void TutorialMode::StrategyTipOne_Group()
{
    //numeric hints
    setCellTile(9, 11, 4);
    setCellTile(10, 11, 5);
    setCellTile(11, 11, 6);

    //row
    setCellTile(12, 11, 3);
    setCellTile(13, 11, 2);
    setCellTile(14, 11, 3);
    setCellTile(15, 11, 3);
    setCellTile(16, 11, 2);
    setCellTile(17, 11, 3);
    setCellTile(18, 11, 3);
    setCellTile(19, 11, 3);
}
//four squares on 8 square row
void TutorialMode::StrategyTipOne_Advanced()
{
    //numeric hints
    setCellTile(10, 11, 7);

    //row
    setCellTile(11, 11, 2);
    setCellTile(14, 11, 3);
    setCellTile(15, 11, 3);
    setCellTile(18, 11, 2);
}
//10x3 puzzle with 6 colored squares in the middle
void TutorialMode::StrategyTipTwo_Single(int step)
{
    switch (step)
    {
    //coloring imaginary squares
    case 1:
        for (int i = 16; i < 20; ++i)
            setCellTile(i, 11, 2);
        break;
    case 2:
        for (int i = 10; i < 14; ++i)
            setCellTile(i, 11, 2);
        break;
    //coloring real squares
    case 3:
        for (int i = 10; i < 20; ++i)
            setCellTile(i, 11, 1);
        setCellTile(14, 11, 3);
        setCellTile(15, 11, 3);
        break;
    default:
        //hints
        for (int i = 10; i < 20; ++i)
            setCellTile(i, 9, 4);
        setCellTile(9, 10, 6);
        setCellTile(9, 11, 9);
        setCellTile(9, 12, 4);
        break;
    }
}

//10x3 puzzle with 4 and 3 colored squares in the middle
void TutorialMode::StrategyTipTwo_Multiple(int step)
{
    switch (step)
    {
    //coloring imaginary squares
    case 1:
        setCellTile(15, 11, 2);
        setCellTile(19, 11, 2);
        break;
    case 2:
        setCellTile(10, 11, 2);
        setCellTile(16, 11, 2);
        break;
    //coloring real squares
    case 3:
        setCellTile(11, 11, 3);
        setCellTile(12, 11, 3);
        setCellTile(13, 11, 3);
        setCellTile(14, 11, 3);
        setCellTile(17, 11, 3);
        setCellTile(18, 11, 3);
        break;
    default:
        //hints
        for (int i = 10; i < 20; ++i)
            setCellTile(i, 9, 4);
        setCellTile(9, 10, 4);
        setCellTile(8, 11, 8);
        setCellTile(9, 11, 6);
        setCellTile(9, 12, 5);
        break;
    }
}

int TutorialMode::updateState()
{
    return drawText();
}

void TutorialMode::toggleStateVisibility(bool show)
{
    _text->clear();
}

void TutorialMode::toggleFadeEffect()
{
    _text->clear();
}

TutorialMode::~TutorialMode()
{
    _text->clear();
}
